package main

import (
	"encoding/json"
	"fmt"
)

var jsonString16 string = `{
        "things": [
            {
                "name": "Alice",
                "age": 37
            },
            {
                "city": "Ipoh",
                "country": "Malaysia"
            },
            {
                "name": "Bob",
                "age": 36
            },
            {
                "city": "Northampton",
                "country": "England"
            }
        ]
    }`

type Person16 struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

type Place16 struct {
	City    string `json:"city"`
	Country string `json:"country"`
}

func decode16(jsonStr []byte) (persons []Person16, places []Place16) {
	var data map[string][]map[string]interface{}
	err := json.Unmarshal(jsonStr, &data)
	if err != nil {
		fmt.Println(err)
		return
	}

	for i := range data["things"] {
		item := data["things"][i]
		if item["name"] != nil {
			persons = addPerson16(persons, item)
		} else {
			places = addPlace16(places, item)
		}

	}
	return
}

func addPerson16(persons []Person16, item map[string]interface{}) []Person16 {
	name := item["name"].(string)
	age := item["age"].(float64)
	person := Person16{name, int(age)}
	persons = append(persons, person)
	return persons
}

func addPlace16(places []Place16, item map[string]interface{}) []Place16 {
	city := item["city"].(string)
	country := item["country"].(string)
	place := Place16{City: city, Country: country}
	places = append(places, place)
	return places
}

func main() {
	personsA, placesA := decode16([]byte(jsonString16))
	fmt.Printf("%+v\n", personsA)
	fmt.Printf("%+v\n", placesA)
}
